package com.oss.service.oss;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oss.dto.oss.DeleteByIdDto;
import com.oss.dto.oss.capitalmanage.*;
import com.oss.entity.oss.CapitalManage;
import com.oss.entity.oss.InvestmentAdvice;
import com.oss.entity.oss.PositionManage;
import com.oss.entity.oss.TradeManage;
import com.oss.enums.IsDeletedEnum;
import com.oss.mapper.oss.CapitalManageMapper;
import com.oss.service.system.DictionaryService;
import com.oss.service.system.UserService;
import com.oss.util.SnowFlakeUtil;
import com.oss.vo.oss.capital.CapitalManageVO;
import com.oss.vo.oss.student.StudentVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CapitalManageService extends ServiceImpl<CapitalManageMapper,CapitalManage> {

    @Autowired
    StudentService studentService;
    @Autowired
    UserService userService;
    @Autowired
    HttpServletRequest  request;
    @Autowired
    DictionaryService dictionaryService;

    public IPage<CapitalManageVO> selectByPage(CapitalManagePageDto dto) {
        LambdaQueryWrapper<CapitalManage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CapitalManage::getIsDeleted, IsDeletedEnum.NO.getFlag());
        wrapper.ge(dto.getMinCapitalType() != null,CapitalManage::getInoutFlag, dto.getMinCapitalType());
        wrapper.le(dto.getMaxCapitalType() != null,CapitalManage::getInoutFlag, dto.getMaxCapitalType());
        wrapper.eq(StringUtils.isNotBlank(dto.getStudentID()),CapitalManage::getStudentID,dto.getStudentID());
        if (dto.getTradeDateStart() != null){
            wrapper.ge(CapitalManage::getTradeDate,dto.getTradeDateStart());
        }
        if (dto.getTradeDateEnd() != null){
            wrapper.le(CapitalManage::getTradeDate,dto.getTradeDateEnd());
        }
        String originHeader = request.getHeader("oss-origin");
        String roleHeader = request.getHeader("oss-role");
        // 校验用户角色 , 如果角色是admin,则查询所有数据
        if (StringUtils.isNotBlank(roleHeader) && roleHeader.contains("admin")) {

        } else {
            // 后台管理端和网页, 只要不是admin角色, 登录时, 只能查询自己账号新增的数据
            // dataSource=1表示系统新增
            wrapper.eq(CapitalManage::getDataSource,1);
            String studentID = request.getHeader("oss-studentID");
            wrapper.eq(CapitalManage::getStudentID,studentID);
            wrapper.in(CapitalManage::getInoutFlag,Arrays.asList(0,1));
        }
        IPage<CapitalManage> page = this.page(new Page<>(dto.getPageNo(), dto.getPageSize()), wrapper);
        Map<String, StudentVO> studentMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(page.getRecords())){
            Set<String> ids = page.getRecords().stream().map(CapitalManage::getStudentID).collect(Collectors.toSet());
            studentMap = studentService.selectByIDs(ids);
        }
        Map<String, StudentVO> finalStudentMap = studentMap;
        Map<String,String> userMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            // 获取创建人和修改人ID
            Set<String> ids = page.getRecords().stream().map(CapitalManage::getCreatorId).collect(Collectors.toSet());
            ids.addAll(page.getRecords().stream().map(CapitalManage::getUpdatorId).collect(Collectors.toSet()));
            userMap = userService.selectByIds(ids);
        }
        Map<String,String> capitalTypeMap = dictionaryService.getDictionaryMapByTypeCode("CapitalType");
        Map<String, String> finalUserMap = userMap;
        return page.convert(entity->{
            CapitalManageVO vo = new CapitalManageVO();
            BeanUtils.copyProperties(entity,vo);
            if (finalStudentMap.containsKey(entity.getStudentID())){
                StudentVO studentVO = finalStudentMap.get(entity.getStudentID());
                vo.setStudentID(studentVO.getId());
                vo.setStudentPhone(studentVO.getPhone());
                vo.setStudentName(studentVO.getName());
                vo.setStudentWechatID(studentVO.getWechatID());
                vo.setStudentAccount(studentVO.getAccount());
            }
            vo.setCreatorName(finalUserMap.get(entity.getCreatorId()));
            vo.setUpdatorName(finalUserMap.get(entity.getUpdatorId()));
            vo.setInoutFlag(capitalTypeMap.get(entity.getInoutFlag().toString()));
            return vo;
        });
    }

    public String add(CapitalManageAddDto dto) {
        CapitalManage entity = new CapitalManage();
        BeanUtils.copyProperties(dto,entity);
        entity.setId(SnowFlakeUtil.getID());
        entity.setDataSource(1);
        this.baseMapper.insert(entity);
        return "操作成功";
    }

    public String updateData(CapitalManageUpdateDto dto) {
        CapitalManage entity = new CapitalManage();
        BeanUtils.copyProperties(dto,entity);
        this.updateById(entity);
        return "操作成功";
    }

    public String delete(DeleteByIdDto dto) {
        LambdaUpdateWrapper<CapitalManage> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(CapitalManage::getId,dto.getId());
        lambdaUpdateWrapper.set(CapitalManage::getIsDeleted,IsDeletedEnum.YES.getFlag());
        this.update(null,lambdaUpdateWrapper);
        return "操作成功";
    }

    /**
     * 根据学员ID, 交易日期,  出/入金查询数据条数(只查询外部推送的)
     * @param studentID
     * @param tradeDate
     * @param inoutFlag
     * @return
     */
    public void deleteByStudentIDAndDate(String studentID, LocalDate tradeDate,Integer inoutFlag) {
        LambdaUpdateWrapper<CapitalManage> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(CapitalManage::getIsDeleted, IsDeletedEnum.NO.getFlag());
        wrapper.eq(CapitalManage::getStudentID,studentID);
        wrapper.eq(CapitalManage::getTradeDate,tradeDate);
        wrapper.eq(CapitalManage::getInoutFlag,inoutFlag);
        wrapper.eq(CapitalManage::getDataSource,0);
        wrapper.set(CapitalManage::getIsDeleted,IsDeletedEnum.YES.getFlag());
        this.update(null,wrapper);
    }


    public String importData(CapitalManageImportDto dto) {
        List<CapitalManage> addList = new ArrayList<>();
        Set<String> accountSet = dto.getList().stream().map(CapitalManageImportDetailDto::getAccount).collect(Collectors.toSet());
        Map<String, String> studentAccountMap = studentService.getByAccountSet(accountSet);
        for (CapitalManageImportDetailDto item : dto.getList()) {
            if (studentAccountMap.containsKey(item.getAccount())) {
                String studentID = studentAccountMap.get(item.getAccount());
                deleteByStudentIDAndDate(studentID,item.getTradeDate(),item.getInoutFlag());
                // 插入
                CapitalManage entity = new CapitalManage();
                BeanUtils.copyProperties(item,entity);
                entity.setStudentID(studentID);
                entity.setId(SnowFlakeUtil.getID());
                entity.setCreatorId("-1");
                addList.add(entity);
            } else {
                log.warn(item.getAccount()+"此账号对应的学员不存在; "+ "需要插入的数据="+ JSON.toJSONString(item));
            }
        }
        if (CollectionUtils.isNotEmpty(addList)){
            this.saveBatch(addList);
        }
        return "操作成功";
    }

    public List<CapitalManage> selectByStudentIdSet(Set<String> ids) {
        if(CollectionUtils.isNotEmpty(ids)) {
            LambdaQueryWrapper<CapitalManage> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CapitalManage::getIsDeleted, IsDeletedEnum.NO.getFlag());
            wrapper.in(CapitalManage::getStudentID,ids);
            return this.list(wrapper);
        } else {
            return new ArrayList<>();
        }
    }
}